﻿using ComClassLibrary;
using KeyboardArg;
using LogLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Xml.Linq;
using Path = System.IO.Path;

//StartupUri = "MainWindow.xaml"
namespace SelectKeyBoard
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// 输入参数
        /// </summary>
        private KeyBoardArgs _keyboardArg;

        public KeyBoardArgs KeyboardArgs
        {
            get { return _keyboardArg; }
        }

        /// <summary>
        /// 当前选中项的值
        /// </summary>
        private string _curSeletedValue = "";

        /// <summary>
        /// 所有按钮配置信息
        /// </summary>
        private List<XButton> _listButtons = new List<XButton>();

        private bool _isCustomDesignUI = false;

        private Dictionary<string, string> NameToAdressMap = new Dictionary<string, string>();

        /// <summary>
        /// 当前页面显示的文字元素和对应键值
        /// </summary>
        List<XNode> listShowNodes = new List<XNode>();

        /// <summary>
        /// 对于多级选项，保存当前选中的根元素名称
        /// </summary>
        private Stack<XNode> StackSelectedNodes = new Stack<XNode>();

        /// <summary>
        /// 窗口隐藏事件
        /// </summary>
        public event EventHandler Hidden;

        private MenuConfig Config = new MenuConfig();

        private XNode SelectedParentNode = null;

        private Style _buttonStyle = null;

        private static string _appDir = "";
        public static string AssemblyDirectory
        {
            get
            {
                if (string.IsNullOrEmpty(_appDir))
                {
                    Assembly ass = Assembly.GetExecutingAssembly();
                    string directory = Path.GetDirectoryName(ass.CodeBase);
                    _appDir = directory.Substring(6);
                }
                return _appDir;
            }
        }

        public MainWindow()
        {
            InitializeComponent();
        }

        public MainWindow(KeyBoardArgs keyboardArg)
        {
            InitializeComponent();
            SetKeyBoardArg(keyboardArg);
        }

        private void LoadButtonStyle()
        {
            if(_buttonStyle == null)
            {
                System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
                string directory = Path.GetDirectoryName(assembly.CodeBase);
                directory = directory.Substring(6);
                string url = Path.Combine(directory, "Dictionary1.xaml");
                ResourceDictionary resourceDictionary = new ResourceDictionary();
                resourceDictionary.Source = new Uri(url, UriKind.Absolute);
                _buttonStyle = (Style)resourceDictionary["ButtonStyle1"];
            }          
        }

        protected void OnWndHidden()
        {
            if (Hidden != null)
            {
                Hidden(this, new EventArgs());
            }
        }

        public bool SetKeyBoardArg(KeyBoardArgs args)
        {
            //MessageBox.Show("test");
            _keyboardArg = args;
            Config.Reset();
            StackSelectedNodes.Clear();
            SelectedParentNode = null;
            //读配置文件
            string exeDir = AssemblyDirectory;
            string xmlFileName = "";
            string iniFileName = "";
            string uiConfigFile = "";
            string langCode = _keyboardArg.LanguageCode;
            if (string.IsNullOrEmpty(_keyboardArg.LanguageCode))
            {
                langCode = "zh-CN";
            }

            xmlFileName = string.Format("{0}\\DIC\\{1}\\{2}.xml", exeDir, langCode, _keyboardArg.DictionaryFileName);
            iniFileName = string.Format("{0}\\DIC\\{1}\\{2}.ini", exeDir, langCode, _keyboardArg.DictionaryFileName);
            uiConfigFile = string.Format("{0}\\DIC\\{1}\\{2}_UI.xml", exeDir, langCode, _keyboardArg.DictionaryFileName);

            if (!File.Exists(xmlFileName) || !File.Exists(iniFileName))
            {
                MessageBox.Show("字典文件" + xmlFileName + "不存在");
                return false;
            }
            if (File.Exists(uiConfigFile))
            {
                _isCustomDesignUI = true;
            }
            else
            {
                _isCustomDesignUI = false;
            }
            Config.TryParse(xmlFileName);
            // 如果加载小区映射文件
            if (_keyboardArg.DictionaryFileName.Equals("StandardAddress"))
            {
                LoadAdressMap(xmlFileName);
            }
            if (_isCustomDesignUI)
            {
                if (!ReadUIConfig(uiConfigFile))
                {
                    return false;
                }
            }
            Config.ReadIniConfig(iniFileName);
            lblTips.FontSize = Config.TitleFontSize;
            lblTips.Content = Config.TitleValue;
            if (!string.IsNullOrEmpty(_keyboardArg.Title))
            {
                lblTips.Content = _keyboardArg.Title;
            }
            CreatSelectButtons();
            return true;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            double ScreenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;//WPF
            double ScreenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;//WPF
            this.Top = ScreenHeight - this.ActualHeight - 200;
            this.Left = (ScreenWidth - this.ActualWidth) / 2;
        }

        private bool ReadUIConfig(string fileName)
        {
            UIConfig config = new UIConfig(fileName);
            if (!config.OnReading())
            {
                MessageBox.Show("读取配置文件" + fileName + "失败: " + config.Error);
                return false;
            }
            _listButtons = config.ListButtons;
            return true;
        }

        private void GetShowKeys()
        {
            listShowNodes.Clear();
            if (SelectedParentNode != null && SelectedParentNode.ChildNodes.Count > 0)
            {
                listShowNodes.AddRange(SelectedParentNode.ChildNodes);
            }
            else
            {
                SelectedParentNode = null;
                var nodes = Config.Nodes.FindAll(r => r.Level == 1);
                listShowNodes.AddRange(nodes);
            }
        }

        private bool CreatSelectButtons()
        {
            GetShowKeys();
            if (listShowNodes.Count == 0)
            {
                return false;
            }
            if (_isCustomDesignUI)
            {
                return CreatCustomButtons();
            }
            else
            {
                return CreatDefaultButtons();
            }
        }

        private bool ContainsNumCharacter(string test)
        {
            return Regex.IsMatch(test, "^(?=.*[0 - 9])(?=.*[a - zA - Z])([a - zA - Z0 - 9]{ 6,20})$");
        }

        private bool CreatDefaultButtons()
        {
            try
            {
                LoadButtonStyle();
                BrushConverter conv = new BrushConverter();
                Brush bru = conv.ConvertFromInvariantString("#FFFFFFFF") as Brush;

                int maxHeight = 0;
                canButtons.Children.Clear();
                int i = 0;
                int curBtnVerticalHeight = 0;//按钮当前垂直高度
                foreach (XNode p in listShowNodes)
                {
                    TextBlock tb = new TextBlock()
                    {
                        Text = p.Key,
                        FontSize = Config.ButtonFontSize,
                        TextWrapping = TextWrapping.Wrap,
                        TextAlignment = TextAlignment.Center
                    };
                    Button btn = new Button
                    {
                        //if(p.Value)
                        Name = "button" + "_" + p.Value,
                        Content = tb,
                        Height = Config.ButtonHeight,
                        Width = Config.ButtonWidth,
                        HorizontalAlignment = HorizontalAlignment.Left,
                        Margin = new Thickness(10, 10, 0, 0),
                        VerticalAlignment = VerticalAlignment.Top,
                        Visibility = Visibility.Visible,
                        FontSize = Config.ButtonFontSize,
                        //Foreground = bru,
                        //Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xF9, 0x86, 0x07)),
                        Tag = p,
                    };                   
                    btn.Click += new RoutedEventHandler(btn_click);                  
                    double canvasLeft = (double)(i * (Config.ButtonWidth + Config.ButtonHorDistance));
                    if ((int)canvasLeft + Config.ButtonWidth + 5 > SelectionArea.Width)  //超出容器，另外起一行
                    {
                        i = 0;
                        curBtnVerticalHeight += (Config.ButtonVerDistance + Config.ButtonHeight);
                        canvasLeft = (double)(i * (Config.ButtonWidth + Config.ButtonHorDistance));
                    }
                    btn.SetValue(Canvas.LeftProperty, canvasLeft + (int)Config.ButtonHorOffSet);
                    btn.SetValue(Canvas.TopProperty, (double)(curBtnVerticalHeight + Config.ButtonVerOffSet));
                    if (maxHeight < curBtnVerticalHeight + Config.ButtonVerOffSet)
                    {
                        maxHeight = curBtnVerticalHeight + Config.ButtonVerOffSet;
                    }
                    //btn.SetResourceReference(System.Windows.Controls.Button.StyleProperty, "ButtonStyle1");
                    btn.Style = _buttonStyle;
                    canButtons.Children.Add(btn);
                    i++;
                }
                canButtons.Height = maxHeight;
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                Console.WriteLine(e);
                return false;
            }
        }

        private bool CreatCustomButtons()
        {
            try
            {
                LoadButtonStyle();
                canButtons.Children.Clear();
                for (int i = 0; i < listShowNodes.Count; i++)
                {
                    XNode p = listShowNodes[i];
                    string Name = "button" + "_" + p.Value.ToString();
                    XButton xBtn = _listButtons.Find(r => r.Name.Equals(Name));
                    if (xBtn != null)
                    {
                        Button btn = xBtn.Creat(canButtons);
                        btn.Tag = p;
                        btn.Style = _buttonStyle;
                        //btn.SetResourceReference(StyleProperty, "ButtonStyle1");
                        if (btn != null)
                        {
                            btn.Click += new RoutedEventHandler(btn_click);
                        }
                    }
                }
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return false;
            }
        }

        List<string> _values = new List<string>();

        private void btn_click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;
            XNode p = (XNode)btn.Tag;
            SelectedParentNode = p;
            if (StackSelectedNodes.Count == 0)
            {
                StackSelectedNodes.Push(p);
            }
            else if (Config.TotalLevel == 2 && StackSelectedNodes.Count == 1)
            {
                StackSelectedNodes.Pop();
                StackSelectedNodes.Push(p);
            }
            else
            {
                StackSelectedNodes.Push(p);
            }
            Config.CurrentLevel++;
            _curSeletedValue = btn.Name.Split('_')[1];
            if (SelectedParentNode.ChildNodes.Count > 0)
            {
                if (CreatSelectButtons())
                {
                    return;
                }
            }
            // 获取返回参数
            UpdateKeyboardArgs(btn);
            _values.Clear();
            //点到最后一级后，发消息回主窗体，并且隐藏窗体
            SendMessage();
            this.Hide();
            OnWndHidden();
        }

        private void UpdateKeyboardArgs(Button btn)
        {
            //获取按钮的值
            string key = ((TextBlock)btn.Content).Text;
            string value = "";
            string[] array = btn.Name.Split('_');
            if (array.Length != 2)
            {
                MessageBox.Show("获取键值失败, 请检查字典配置是否正确.");
            }
            else
            {
                value = array[1];
            }
            _keyboardArg.PassageType = SendMessageType.Response;
            _keyboardArg.Content = key;
            _keyboardArg.Command = "OK";
            XNode node = btn.Tag as XNode;
            if (!string.IsNullOrEmpty(node.Code))
            {
                _keyboardArg.Code = node.Code;
            }
            else if (!string.IsNullOrEmpty(node.Value))
            {
                _keyboardArg.Code = node.Value;
            }
            else
            {
                _keyboardArg.Code = value;
            }
            GetFullContent();
        }

        private void GetFullContent()
        {
            _keyboardArg.FullContent = "";
            List<XNode> SelectedNodes = new List<XNode>(StackSelectedNodes.ToArray());
            SelectedNodes.Reverse();
            if (_keyboardArg.DictionaryFileName.Equals("ShiXian"))// || _keyboardArg.DictionaryFileName.Equals("StayPlace")) // 籍贯，省市县
            {
                if (SelectedNodes.Count == 3)
                {
                    if (SelectedNodes[2].Key.EndsWith("县") || SelectedNodes[2].Key.EndsWith("旗"))
                    {
                        _keyboardArg.FullContent += SelectedNodes[0].Key + SelectedNodes[2].Key;
                    }
                    else
                    {
                        for (int i = 0; i < SelectedNodes.Count; i++)
                        {
                            string val = SelectedNodes[i].Key;
                            _keyboardArg.FullContent += val;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < SelectedNodes.Count; i++)
                    {
                        string val = SelectedNodes[i].Key;
                        _keyboardArg.FullContent += val;
                    }
                }
                return;
            }
            for (int i = 0; i < SelectedNodes.Count; i++)
            {
                string val = SelectedNodes[i].Key;
                if (_keyboardArg.DictionaryFileName.Equals("StandardAddress"))
                {
                    _keyboardArg.FullContent += val + ",";
                }
                else
                {
                    _keyboardArg.FullContent += val;
                }
            }
            if (_keyboardArg.DictionaryFileName.Equals("StandardAddress"))
            {
                string key = SelectedNodes[0].Key;
                if (_keyboardArg.FullContent.EndsWith(","))
                {
                    _keyboardArg.FullContent = _keyboardArg.FullContent.Remove(_keyboardArg.FullContent.Length - 1, 1);
                }
                if (NameToAdressMap.ContainsKey(key))
                {
                    _keyboardArg.FullContent = NameToAdressMap[key] + "," + _keyboardArg.FullContent;
                }
            }
        }

        private bool SendMessage()
        {
            if (_keyboardArg.MsgReceiver == IntPtr.Zero)
            {
                MessageBox.Show("句柄错误", "句柄错误");
                return false;
            }
            int uMsg = (int)MessageType.WM_COPYDATA;
            string strMsgText = JsonHandler.ConvertToJsonString(_keyboardArg);
            byte[] data = System.Text.Encoding.UTF8.GetBytes(strMsgText);
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            cds.dwData = (IntPtr)uMsg;
            cds.cbData = data.Length;
            cds.lpData = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, cds.lpData, data.Length);
            Message.SendMessage(_keyboardArg.MsgReceiver, uMsg, 0, ref cds);
            return true;
        }

        private void buttonClose_Click(object sender, RoutedEventArgs e)
        {
            if (_keyboardArg == null)
            {
                this.Hide();
                OnWndHidden();
                return;
            }
            int uMsg = (int)MessageType.WM_COPYDATA;
            _keyboardArg.Content = "";
            _keyboardArg.Command = "Cancel";
            string strMsgText = JsonHandler.ConvertToJsonString(_keyboardArg);
            byte[] data = System.Text.Encoding.UTF8.GetBytes(strMsgText);
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            cds.dwData = (IntPtr)uMsg;
            cds.cbData = data.Length;
            cds.lpData = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, cds.lpData, data.Length);
            Message.SendMessage(_keyboardArg.MsgReceiver, uMsg, 0, ref cds);
            this.Hide();
            OnWndHidden();
        }

        private void buttonBackToLast_Click(object sender, RoutedEventArgs e)
        {
            Console.WriteLine("摁了返回键.");
            if (Config.CurrentLevel == 1)
            {
                return;
            }
            if (Config.CurrentLevel > 1)
            {
                if (Config.CurrentLevel > 2)
                {
                    XNode node = StackSelectedNodes.Pop();
                    SelectedParentNode = node.Parent;
                }
                else
                {
                    SelectedParentNode = null;
                    StackSelectedNodes.Clear();
                }
                Config.CurrentLevel--;
                CreatSelectButtons();
            }
        }

        /// <summary>
        /// 加载小区地址的映射表
        /// </summary>
        private void LoadAdressMap(string xmlFile)
        {
            try
            {
                XDocument xmlDoc = XDocument.Load(xmlFile);
                XElement root = xmlDoc.Element("root");
                if (root == null)
                    return;
                NameToAdressMap.Clear();
                IEnumerable<XElement> elems = root.Elements("Level1");
                foreach (XElement e in elems)
                {
                    string key = e.Attribute("key").Value.Trim();
                    string roadName = e.Attribute("RoadName").Value.Trim();
                    string houseNumber = e.Attribute("HouseNumber").Value.Trim();
                    string adress = roadName + "," + houseNumber + "号";
                    NameToAdressMap.Add(key, adress);
                }
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
        }

        private void 蓝色_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Image img = (Image)sender;
            _keyboardArg.PassageType = SendMessageType.Response;
            _keyboardArg.Content = img.Name;
            _keyboardArg.Code = img.Name;
            _values.Clear();
            //点到最后一级后，发消息回主窗体，并且隐藏窗体
            SendMessage();
            this.Hide();
            OnWndHidden();
        }

    }
}
